using UnityEngine;
using UnityEngine.Rendering;

namespace SSRP
{
    public partial class SSRPCameraRenderer
    {
        // CMD Buffer
        const string c_BufferName = "Render Camera";
        CommandBuffer m_Buffer = new CommandBuffer {
            name = c_BufferName
        };

        static ShaderTagId m_UnlitShaderTagId = new ShaderTagId("SRPDefaultUnlit");
        static ShaderTagId m_LitShaderTagId = new ShaderTagId("SSRPLit");
        

        ScriptableRenderContext m_Context;
        Camera m_Camera;
        
        CullingResults m_CullingResults;

        public void Render(ScriptableRenderContext context, Camera camera, bool useDynamicBatching,
            bool useGPUInstancing)
        {
            m_Context = context;
            m_Camera = camera;

            PrepareBuffer();
            PrepareForSceneWindow();
            if (!Cull()) return;
            
            Setup();
            DrawVisibleGeometry(useDynamicBatching, useGPUInstancing);
            DrawUnsupportedShaders();
            DrawGizmos();
            Submit();
        }

        void Setup()
        {
            m_Context.SetupCameraProperties(m_Camera);
            CameraClearFlags flags = m_Camera.clearFlags;
            m_Buffer.ClearRenderTarget(
                flags <= CameraClearFlags.Depth,
                flags == CameraClearFlags.Color,
                flags == CameraClearFlags.Color ?
                    m_Camera.backgroundColor.linear : Color.clear
            );
            m_Buffer.BeginSample(m_SampleName);
            ExecuteBuffer();
        }

        void DrawVisibleGeometry(bool useDynamicBatching, bool useGPUInstancing)
        {
            // 绘制不透明物体
            var sortingSettings = new SortingSettings(m_Camera) {criteria = SortingCriteria.CommonOpaque};
            var drawingSettings = new DrawingSettings(m_UnlitShaderTagId, sortingSettings)
            {
                enableDynamicBatching = useDynamicBatching,
                enableInstancing = useGPUInstancing,
            };
            drawingSettings.SetShaderPassName(1, m_LitShaderTagId);
            var filteringSettings = new FilteringSettings(RenderQueueRange.opaque);
            m_Context.DrawRenderers(m_CullingResults, ref drawingSettings, ref filteringSettings);
         
            // 绘制天空盒
            m_Context.DrawSkybox(m_Camera);
            
            // 绘制透明物体
            sortingSettings.criteria = SortingCriteria.CommonTransparent;
            drawingSettings.sortingSettings = sortingSettings;
            filteringSettings.renderQueueRange = RenderQueueRange.transparent;
            m_Context.DrawRenderers(m_CullingResults, ref drawingSettings, ref filteringSettings);
        }

        void Submit()
        {
            m_Buffer.EndSample(m_SampleName);
            ExecuteBuffer();
            m_Context.Submit();
        }

        void ExecuteBuffer()
        {
            m_Context.ExecuteCommandBuffer(m_Buffer);
            m_Buffer.Clear();
        }

        bool Cull()
        {
            if (m_Camera.TryGetCullingParameters(out ScriptableCullingParameters p))
            {
                m_CullingResults = m_Context.Cull(ref p);
                return true;   
            }
            return false;
        }
    }
}